/*
-----------------------------------------------------------------------------
This source file is part of Labor3D
(Labor 3D Graphics Engine)

Copyright (c) 2009-2020 Rock Mao
* creator : Rock Mao
* created : 2009-5-3   22:29
* filename: LaborVectorFunction.h
-----------------------------------------------------------------------------
*/

#ifndef __LABORVECTORFUNCTION_INCLUDE__
#define __LABORVECTORFUNCTION_INCLUDE__

#include "../LaborCoreDef.h"
#include "LaborMathDecl.h"
#include "LaborMathInclude.h"
//#include "LaborMatrix3Function.h"
//#include "LaborMatrix4Function.h"

NAMESPACE_LABOR3D_BEGIN

 inline void LABORCORE_API projectToPlane(const CLPlane& p, CLPoint3& ptIn )
{
	ptIn -= (p.d + (ptIn|p.n))*p.n;
}

///< useful for calculating the angle between the normal of the plane, and another normal
inline float			 LABORCORE_API dotPlaneNormal( const CLPlane &plane, const CLPoint3& ptIn )
{
	return plane.n.x* ptIn.x + plane.n.y* ptIn.y + plane.n.z* ptIn.z + plane.d*0.f;
}

///< useful for determining the plane's relationship with a coordinate in 3-D space
inline float		 LABORCORE_API dotPlaneCoord( CLPlane &plane, const CLPoint3& ptIn )
{
	return plane.n.x* ptIn.x + plane.n.y* ptIn.y + plane.n.z* ptIn.z + plane.d*1.f;
}


inline void  LABORCORE_API projectToScreen(float halfrenderwidth, float halfrenderheight, const CLMatrix4x4& mat, CLPoint4& projected , const CLPoint3& ptIn)
{
	CLPoint4 ptIn4 = CLPoint4( ptIn.x,  ptIn.y,  ptIn.z, 1.0f );
	LM_Mul( mat, ptIn4, projected );
	//projected = CLPoint4( ptIn.x,  ptIn.y,  ptIn.z, 1.0f) * mat;
	projected.w = 1.0f / projected.w;

	projected.x*=projected.w;
	projected.y*=projected.w;
	projected.z*=projected.w;

	projected.x *= halfrenderwidth;		projected.x += halfrenderwidth;
	projected.y *= -halfrenderheight;	projected.y += halfrenderheight;
}

//! Returns smallest axis
inline	ELPointComponent	smallestAxis( const CLPoint3 & ptIn )
{
	ELPointComponent m = _X;
	if(ptIn[_Y] < ptIn[m]) m = _Y;
	if(ptIn[_Z] < ptIn[m]) m = _Z;
	return m;
}

//! Returns largest axis
inline ELPointComponent	largestAxis(const CLPoint3 & ptIn)
{
	//const float* Vals = &x;
	ELPointComponent m = _X;
	if(ptIn[_Y] > ptIn[m]) m = _Y;
	if(ptIn[_Z] > ptIn[m]) m = _Z;
	return m;
}

NAMESPACE_LABOR3D_END
#endif
